﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using SocialLearning.CoreInterfaces;
using SocialLearning;
using System.Text;

namespace ArchitectureV2
{
    [ServiceContract]
    public interface ISocialLearningService
    {
        // Will return the session ID if the login succeeded.
        // Or null if the login failed.
        // Use InvokeMethod to retrieve specific user data for
        // the current user.
        [OperationContract]
        byte[] Login(string username, string password);

        // Call this before disconnecting.
        [OperationContract]
        void Logout(byte[] sessionId);

        // Test if logged in:
        [OperationContract]
        bool IsLoggedIn(byte[] sessionId);

        // Get all loaded modules:
        [OperationContract]
        string[] GetModuleList(byte[] sessionId);

        // Get all methods in a given module:
        [OperationContract]
        string[] GetMethodList(byte[] sessionId, string module);

        // The following is only accessible when logged in:

        // Get the currently logged in user:
        [OperationContract]
        User GetUser(byte[] sessionId);

        // Get any user:
        [OperationContract]
        User GetSomeUser(byte[] sessionId, string username);

        // Sets the client IP / UDP port address which will receive pings
        // from modules.
        [OperationContract]
        void SetClientPingEndpoint(byte[] sessionId, string ip, int port);

        // Invokes a method on a loaded module and optionally returns
        // data (or null otherwise).
        [OperationContract]
        [ServiceKnownType("GetTypes", typeof(KnownTypes))]
        Result InvokeMethod(byte[] sessionId, string module, string method, object[] parameters);

        [OperationContract]
        AwesomeResult InvokeMethodAwesome(byte[] sessionId, string module, string method, string parameters);

        // DEBUG ONLY! Gets the number of users registered for pinging.
        [OperationContract]
        int GetActivePingedUsers(byte[] sessionId);
    }

    [ServiceContract]
    public interface ISocialLearningRestService
    {
        // Will return the session ID if the login succeeded.
        // Or null if the login failed.
        // Use InvokeMethod to retrieve specific user data for
        // the current user.
        [OperationContract(Name = "LoginRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "login",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        byte[] Login(string username, string password);

        // Call this before disconnecting.
        [OperationContract(Name = "LogoutRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "logout",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        void Logout(byte[] sessionId);

        // Test if logged in:
        [OperationContract(Name = "IsLoggedInRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "loggedin",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        bool IsLoggedIn(byte[] sessionId);

        // Get all loaded modules:
        [OperationContract(Name = "GetModuleListRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "modules",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        string[] GetModuleList(byte[] sessionId);

        // Get all methods in a given module:
        [OperationContract(Name = "GetMethodListRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "methods",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        string[] GetMethodList(byte[] sessionId, string module);

        // The following is only accessible when logged in:

        // Get the currently logged in user:
        [OperationContract(Name = "GetUserRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "user",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        User GetUser(byte[] sessionId);

        // Get any user:
        [OperationContract(Name = "GetSomeUserRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "userinfo",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        User GetSomeUser(byte[] sessionId, string username);

        // Sets the client IP / UDP port address which will receive pings
        // from modules.
        [OperationContract(Name = "SetClientPingEndpointRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "pingme",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        void SetClientPingEndpoint(byte[] sessionId, string ip, int port);

        // Invokes a method on a loaded module and optionally returns
        // data (or null otherwise).
        [OperationContract(Name = "InvokeMethodRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "invoke",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        [ServiceKnownType("GetTypes", typeof(KnownTypes))]
        Result InvokeMethod(byte[] sessionId, string module, string method, object[] parameters);

        // DEBUG ONLY! Gets the number of users registered for pinging.
        [OperationContract(Name = "GetActivePingedUsersRest")]
        [WebInvoke(BodyStyle = WebMessageBodyStyle.Wrapped, UriTemplate = "activecount",
            Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
        int GetActivePingedUsers(byte[] sessionId);
    }
}
